'''
pygeom -- Python Geometric Engine
geset -- GE Sets

A GESet is a convenience that allows a user to treat a collection
of GEs as a set that can be intersected, unioned, or filtered by
properties.
'''

from pygeom import cls

# XXX Would set be a better base here? Am I shooting myself
# in the foot?
class GESet(object):
    def __init__(self, init=None):
        self._list=list(init or [])
    @property
    def List(self):
        return self._list
    def Append(self, ge):
        self._list.append(ge)
    def Extend(self, geiter):
        self._list.append(geiter)
    def Remove(self, ge):
        self._list.remove(ge)
    def __len__(self, ge):
        return len(self._list)
    #OK, enough pedantry. Get to the guts:
    #(and thanks to sets.py for defining these terms)
    def Union(self, geset):
        return GESet(self._list[:].extend(geset._list))
    __or__=Union
    def Intersection(self, geset):
        return GESet([i for i in self._list if i in geset._list])
    __and__=Intersection
    def SymmetricDifference(self, geset):
        ret=[i for i in self._list if i not in geset._list]
        ret.extend([i for i in geset._list if i not in self._list])
        return GESet(ret)
    __xor__=SymmetricDifference
    def Difference(self, geset):
        return GESet([i for i in self._list if i not in geset._list])
    __sub__=Difference
    def IsSubset(self, geset):
        for i in self._list:
            if i not in geset._list:
                return False
        return True
    def __contains__(self, other):
        if isinstance(other, self.__class__):
            return self.IsSubset(other)
        else:
            return other in self._list
    def IsSuperset(self, geset):
        return geset.IsSubset(self)
    #That's set protocol. Now for filtering:
    def Filter(self, func, transform=None):
        tform=transform or lambda x: x
        return GESet([tform(i) for i in self._list if func(i)])
    def FilterByClass(self, kls):
        return self.Filter(lambda x: cls.Check(x.Class, kls))
    def TransformAll(self, tfunc):
        return self.Filter(lambda x: True, tfunc)
    def TransformByClass(self, kls, tfunc):
        return self.Filter(lambda x: cls.Check(x.Class, kls), tfunc)
